package com.ficv.tucanalmovil.web;

import static javax.measure.unit.NonSI.DEGREE_ANGLE;
import static javax.measure.unit.SI.METER;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;

import javax.measure.quantity.Length;
import javax.servlet.http.HttpServletRequest;

import org.jscience.geography.coordinates.LatLong;
import org.jscience.geography.coordinates.UTM;
import org.jscience.geography.coordinates.crs.CoordinatesConverter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.roo.addon.web.mvc.controller.scaffold.RooWebScaffold;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.ficv.tucanalmovil.dominio.Actividad;
import com.ficv.tucanalmovil.dominio.AlertaAprox;
import com.ficv.tucanalmovil.dominio.Avisos;
import com.ficv.tucanalmovil.dominio.AvisosList;
import com.ficv.tucanalmovil.dominio.Colores;
import com.ficv.tucanalmovil.dominio.Contactos;
import com.ficv.tucanalmovil.dominio.Device;
import com.ficv.tucanalmovil.dominio.Empresa;
import com.ficv.tucanalmovil.dominio.People;
import com.ficv.tucanalmovil.dominio.Peticiones;
import com.ficv.tucanalmovil.dominio.Positions;
import com.ficv.tucanalmovil.web.beans.ActivitiesCount;

@RequestMapping("/devices")
@Controller
@RooWebScaffold(path = "devices", formBackingObject = Device.class)
public class DeviceController {
	
	private static final long GENERIC_ANDROID_DEVICE = 1L;
	private static final String DEFAULT_EMPRESA_CODE = "epl";
	
	private static final Logger logger = LoggerFactory.getLogger(DeviceController.class);

	
	@RequestMapping(value="msg", method=RequestMethod.GET)
	public @ResponseBody String getMsg(@RequestParam String androidId) throws Exception {		
		
		logger.info("fetching Msg");
		
		String result="";
		Device dev =  null;	
		try {
		
			 dev=Device.findDevicesByAndroidIdEquals(androidId).getResultList().get(0);
		

		
		} catch(Throwable e)  {
			logger.error(e.getMessage(),e);

		}
		
		if(dev==null) {
			dev = Device.findDevice(GENERIC_ANDROID_DEVICE);
			Device newDev = new Device();
			newDev.setMensaje(dev.getMensaje());
			newDev.setAndroidId(androidId);
			newDev.persist();
		}
		
		result=dev.getMensaje();
		
		return result;

	}
	
	
	@SuppressWarnings("unchecked")
	@RequestMapping(value="allmsg", method=RequestMethod.GET)
	public @ResponseBody AvisosList getAllMsg(@RequestParam String androidId, @RequestParam String last) throws Exception {		
		
		logger.info("fetching AllMsg");
		
		AvisosList avs = new AvisosList();
		Device dev =  null;	
		try {
		
			 dev=Device.findDevicesByAndroidIdEquals(androidId).getResultList().get(0);
		

		
		} catch(Throwable e)  {
			logger.error(e.getMessage(),e);

		}
		
		Empresa emp=Empresa.findEmpresasByCodeEquals(DEFAULT_EMPRESA_CODE).getResultList().get(0);
		
		if(dev==null) {
			dev = Device.findDevice(GENERIC_ANDROID_DEVICE);
			Device newDev = new Device();
			dev.persist();
			dev=newDev;
			dev.setMensaje(dev.getMensaje());
			dev.setAndroidId(androidId);
		}
		
//		Avisos av = new Avisos();
//
//		av.setEmpresa(emp);
//		Calendar cal = new GregorianCalendar();
//		cal.setTime(new Date());
//		av.setHora(cal.toString());
//		av.setTexto(dev.getMensaje());
//		av.setTipo(Avisos.TYPE_OUT);
//		av.persist();
//		dev.getAvisos().add(av);
//		dev.merge();

		
		
		avs.setAvisos(Avisos.findAvisosesByDeviceAndEmpresaAndIdGreaterThan(dev,emp,Long.valueOf(last)).getResultList());
		
		return avs;

	}	
	
	
	@RequestMapping(value="emp", method=RequestMethod.GET, produces = "application/xml")
	public @ResponseBody Empresa getEmpresa(@RequestParam String code) {		
		logger.info("fetching empresas");

		Empresa emp =  null;	
		try {
		
			 emp=Empresa.findEmpresasByCodeEquals(code).getResultList().get(0);
					 
		
		} catch(Throwable e)  {
			logger.error(e.getMessage(),e);

		}

		
		return emp;
		 
	}
	
	@RequestMapping(value="contact", method=RequestMethod.GET)
	public @ResponseBody String getContact(@RequestParam String androidId, @RequestParam String medio) throws Exception {		
		
		logger.info("fetching contact");
		
		String result="";
		Device dev =  null;	
		try {
		
			 dev=Device.findDevicesByAndroidIdEquals(androidId).getResultList().get(0);
		

		
		} catch(Throwable e)  {
			logger.error(e.getMessage(),e);

		}
		
		if(dev==null) {
			dev = Device.findDevice(GENERIC_ANDROID_DEVICE);
			Device newDev = new Device();
			newDev.setMensaje(dev.getMensaje());
			newDev.setAndroidId(androidId);
			newDev.setNumero(medio);
			newDev.persist();
			dev=newDev;
		}

			dev.setNumero(medio);
			Avisos av = new Avisos();
			Empresa emp=Empresa.findEmpresasByCodeEquals(DEFAULT_EMPRESA_CODE).getResultList().get(0);
			av.setEmpresa(emp);
			Calendar cal = new GregorianCalendar();
			cal.setTime(new Date());
			av.setHora(cal.getTime().toString());
			av.setTexto(medio);
			av.setTipo(Avisos.TYPE_IN);
			av.persist();
			dev.getAvisos().add(av);
			dev.merge();
		
		
		return result;

	}
	
	@RequestMapping(value="url", method=RequestMethod.GET)
	public @ResponseBody String getBaseURL() throws Exception {		
		
		logger.info("fetching url");
		
		String result="http://10.42.0.1:8080/tucanalmovil/devices/";
//		String result="http://192.168.2.141:8080/tucanalmovil/devices/";
//		String result="http://192.168.43.131:8080/tucanalmovil/devices/";

		return result;

	}	
	
	@RequestMapping(value="peopleTest", method=RequestMethod.GET, produces = "application/json")
	public @ResponseBody ResponseEntity<List<People>> getPeople(
			@RequestParam String deviceId,
			@RequestParam String activity,
			@RequestParam String mode) {		

		List<People> people =  null;	
		try {
		
			People p = People.findPeoplesByDeviceIdEquals(deviceId).getSingleResult();
			p.setOnline(new Date());
			p.merge();	
			
			Calendar minHora = new GregorianCalendar();
				minHora.setTime(new Date());
				minHora.add(Calendar.DAY_OF_MONTH,-1);

				
				people=People.findPeoplesByActivityEqualsAndModeEqualsAndOnlineGreaterThan(activity, mode, minHora.getTime()).getResultList();
				//people=People.findPeoplesByActivityEqualsAndModeEquals(activity, mode).getResultList();
				
		} catch(Throwable e)  {
			logger.error(e.getMessage(),e);
		}



		return new ResponseEntity<List<People>>(people, getResponseHeaders(), HttpStatus.OK);
		 
	}	
	
	@RequestMapping(value="peopleCiudad", method=RequestMethod.GET, produces = "application/json")
	public @ResponseBody ResponseEntity<List<People>> peopleCiudad(			
			@RequestParam String deviceId,
			@RequestParam String activity,
			@RequestParam String mode) {	

		List<People> people =  null;	
		try {
		
				People p = People.findPeoplesByDeviceIdEquals(deviceId).getSingleResult();
			
				Calendar minHora = new GregorianCalendar();
				minHora.setTime(new Date());
				minHora.add(Calendar.DAY_OF_MONTH,-1);
			
				people=People.findPeoplesByActivityEqualsAndModeEqualsAndPoblacionEqualsAndHoraGreaterThan(activity, mode, p.getPoblacion(), minHora.getTime()).getResultList();

		} catch(Throwable e)  {
			logger.error(e.getMessage(),e);
		}



		return new ResponseEntity<List<People>>(people, getResponseHeaders(), HttpStatus.OK);
		 

	}		
	
	
	
	@RequestMapping(value="peopleAround", method=RequestMethod.POST, produces = "application/json")
	public @ResponseBody ResponseEntity<List<People>> getPeopleAround(
			@RequestParam String deviceId,
			@RequestParam String activity,
			@RequestParam String mode) {		

		int OFFSET=20000;
		
		List<People> people = null;
//		List<People> people =  new ArrayList<People>();	
		try {
		
				People p = People.findPeoplesByDeviceIdEquals(deviceId).getSingleResult();
			
				if(p.getRadioKm()!=null && p.getRadioKm()>0) OFFSET=p.getRadioKm()*1000;
				
				Calendar minHora = new GregorianCalendar();
				minHora.setTime(new Date());
				minHora.add(Calendar.DAY_OF_MONTH,-1);
				
				CoordinatesConverter<LatLong, UTM> latLongToUTM = LatLong.CRS.getConverterTo(UTM.CRS);
				
				LatLong latlng = LatLong.valueOf(p.getLat(), p.getLon(), DEGREE_ANGLE);
				UTM utm = latLongToUTM.convert(latlng);
				
				UTM utmPoint = UTM.valueOf(utm.longitudeZone(), utm.latitudeZone(), 
						utm.getCoordinates()[0] - OFFSET, utm.getCoordinates()[1] + OFFSET, METER);
				
				UTM utmOffset = UTM.valueOf(utm.longitudeZone(), utm.latitudeZone(), 
						utm.getCoordinates()[0] - OFFSET + 2*OFFSET, utm.getCoordinates()[1] + OFFSET - 2*OFFSET, Length.UNIT);
				
				CoordinatesConverter<UTM,LatLong> utmToLatLong = UTM.CRS.getConverterTo(LatLong.CRS);
				LatLong llPoint = utmToLatLong.convert(utmPoint);
				LatLong llOffset = utmToLatLong.convert(utmOffset);

			
			
				people=People.findPeople(activity, mode, minHora.getTime(),p,llPoint.getCoordinates()[1],llOffset.getCoordinates()[1],llOffset.getCoordinates()[0],llPoint.getCoordinates()[0]).getResultList();
				//people=People.findPeoplesByActivityEqualsAndModeEqualsAndHoraBetween(activity, mode, minHora.getTime(), maxHora.getTime()).getResultList();
				//people=People.findPeoplesByActivityEqualsAndModeEquals(activity, mode).getResultList();
				
		} catch(Throwable e)  {
			logger.error(e.getMessage(),e);
		}



		return new ResponseEntity<List<People>>(people, getResponseHeaders(), HttpStatus.OK);
		 
	}	
	
	@RequestMapping(value="people", method=RequestMethod.GET, produces = "application/json")
	public @ResponseBody ResponseEntity<List<People>> getPeople(@RequestParam String activity) {		

		List<People> people =  null;	
		try {	 
				people=People.findPeoplesByActivityEquals(activity).getResultList();
		} catch(Throwable e)  {
			logger.error(e.getMessage(),e);

		}

		return new ResponseEntity<List<People>>(people, getResponseHeaders(), HttpStatus.OK);
		 
	}
	
	
	@RequestMapping(value="peopleId", method=RequestMethod.GET, produces = "application/json")
	public @ResponseBody ResponseEntity<Long> getPeopleId(	HttpServletRequest request,
															@RequestParam String deviceId,
															@RequestParam String nick,
															@RequestParam String comment,
															@RequestParam String abbr,
															@RequestParam String latency,
															@RequestParam String activity,
															@RequestParam String color,
															@RequestParam String mode
															) {		
		
		if(deviceId.equalsIgnoreCase("-1")) deviceId=request.getHeader("X-Cluster-Client-IP");
		else if(deviceId.equalsIgnoreCase("-2")) deviceId=request.getRemoteUser();		
		if(deviceId==null || deviceId.equalsIgnoreCase("")) deviceId= request.getRemoteAddr();

		
		logger.info("fetching peopleId for device: " + deviceId);

		
		
		Long result=-1L;
		People people =  null;	
		try {
		
			people=People.findPeoplesByDeviceIdEquals(deviceId).getSingleResult();

			
		} catch(Throwable e)  {
			logger.error(e.getMessage(),e);
		}

		if(people==null) {
			people=new People();
		}

			
			people.setDeviceId(deviceId);
			
			
			people.setNick(nick);
			people.setColor(color);
			people.setComment(comment);
			people.setAbbr(abbr);
			people.setMode(mode);
			
			
			if(nick!=null && !nick.equalsIgnoreCase("") && (abbr==null || abbr.equalsIgnoreCase(""))) people.setAbbr(nick.substring(0,1));
			
			people.setActivity(activity);
			people.setLatency(latency);
			
			if(people.getId()!=null)
				people.merge();
			else
				people.persist();
			
			people.flush();
			result=people.getId();

		logger.info("got peopleId " + result);

		
		return new ResponseEntity<Long>(result, getResponseHeaders(), HttpStatus.OK);
		 
	}
	
	
	@RequestMapping(value="config", method=RequestMethod.POST, produces = "application/json")
	public @ResponseBody ResponseEntity<People> getConfig(	HttpServletRequest request,
															@RequestParam String deviceId,
															@RequestParam String nick,
															@RequestParam String comment,
															@RequestParam String abbr,
															@RequestParam String latency,
															@RequestParam String activity,
															@RequestParam String color,
															@RequestParam String mode,
															@RequestParam String refresh,
															@RequestParam String radio,
															@RequestParam String telefono
															) {		
		
		if(deviceId.equalsIgnoreCase("-1")) deviceId=request.getHeader("X-Cluster-Client-IP");
		else if(deviceId.equalsIgnoreCase("-2")) deviceId=request.getRemoteUser();
		if(deviceId==null || deviceId.equalsIgnoreCase("")) deviceId= request.getRemoteAddr();

		
		logger.info("fetching peopleId for device: " + deviceId);

		
		
		Long result=-1L;
		People people =  null;	
		try {
		
			people=People.findPeoplesByDeviceIdEquals(deviceId).getSingleResult();

			
		} catch(Throwable e)  {
			logger.info(e.getMessage());
		}

		if(people==null) {
			people=new People();
		}

			
			people.setDeviceId(deviceId);
			
			
			if(nick!=null && !nick.equalsIgnoreCase("")) people.setNick(nick);
			if(people.getColor()==null || people.getColor().equalsIgnoreCase("") || people.getColor().equalsIgnoreCase("FFFFFF") 
					|| people.getHora()==null || ((new Date()).getTime() - people.getHora().getTime() > 3600000)) 
							people.setColor(getColor(activity));
			
			people.setComment(comment);
			people.setAbbr(abbr);
			people.setMode(mode);
			people.setRadioKm(Integer.parseInt(radio));
			people.setOnline(new Date());
			people.setTelefono(telefono);
			
			if(nick!=null && !nick.equalsIgnoreCase("") && (abbr==null || abbr.equalsIgnoreCase(""))) people.setAbbr(nick.substring(0,1));
			
			people.setActivity(activity);
			
//			if(people.getId()==null) { 				
				people.setRefresh(refresh);
//			}
			
			
				
			people.setLatency(latency);
			
			if(people.getId()!=null)
				people.merge();
			else
				people.persist();
			
			people.flush();
			result=people.getId();

		


		
		logger.info("got peopleId " + result);

		
		return new ResponseEntity<People>(people, getResponseHeaders(), HttpStatus.OK);
		 
	}
	
	
	private synchronized String getColor(String activity) {
		String color="FFFFFF";
		try {
			Actividad act = Actividad.findActividadsByDescripcionEquals(activity).getSingleResult();
			Colores col=Colores.findColores(act.getLastColor().getId()>255?1:act.getLastColor().getId()+1);
			act.setLastColor(col);
			act.merge();
			StringTokenizer st = new StringTokenizer(col.getRgb(),",");
			color = String.format("%02x%02x%02x", Integer.parseInt(st.nextToken()), Integer.parseInt(st.nextToken()), Integer.parseInt(st.nextToken()));		
		}
		catch(Throwable e) {
			logger.error(e.getMessage(),e);
		}
		
		return color;
	}

	
	
	@RequestMapping(value="addToGroup", method=RequestMethod.POST, produces = "application/json")
	public @ResponseBody ResponseEntity<String> addToGroup(HttpServletRequest request,
																@RequestParam String deviceId,
																@RequestParam String groupId,
																@RequestParam(value="members[]") String[] members
																) {	
																														
		String result="{\"result\": \"KO\"}";

		try {
		
	
			People remite=People.findPeoplesByDeviceIdEquals(deviceId).getSingleResult();
			People destino=People.findPeoplesByDeviceIdEquals(groupId).getSingleResult();
		
				
				for(int i=0; i<members.length; i++) {
					People member=People.findPeoplesByDeviceIdEquals(members[i]).getSingleResult();
					Contactos c= new Contactos();
					c.setContactoA(destino);
					c.setContactoB(member);	
					c.setBlockedAtoB(0);
					c.setBlockedBtoA(0);
					c.setBToA(false);

					Peticiones pet = new Peticiones();
					
					pet.setHora(new Date());
					pet.setTexto("__31");
					pet.setRemite(member);
					pet.setDestinatario(destino);
					pet.setConfirmar(false);					
					pet.persist();
					
					c.setAToB(true);
					c.setLastMsgId(pet.getId());
					c.setHora(new Date());						
					c.persist();

				}

		result="{\"result\": \"OK\"}";

		} catch(Throwable e)  {
			logger.error(e.getMessage(),e);

		}

		return new ResponseEntity<String>(result, getResponseHeaders(), HttpStatus.OK);
		 
	}
	
	@RequestMapping(value="addGroup", method=RequestMethod.POST, produces = "application/json")
	public @ResponseBody ResponseEntity<String> addGroup(HttpServletRequest request,
																@RequestParam String deviceId,
																@RequestParam String groupName,
																@RequestParam(value="members[]") String[] members
																) {	
																														
		String result="{\"result\": \"KO\"}";

		try {
		
			String groupId= "__group_" + deviceId + "_" + (new Date()).getTime();
			getConfig(request, groupId, groupName, "Los mejores", "!", "60000", "newbieActivity", "FFFFFF", "0.1.11", "10000","20","");
			
	
			People remite=People.findPeoplesByDeviceIdEquals(deviceId).getSingleResult();
			People destino=People.findPeoplesByDeviceIdEquals(groupId).getSingleResult();
			
	
			Contactos c= new Contactos();
			c.setContactoA(remite);
			c.setContactoB(destino);	
			c.setBlockedAtoB(0);
			c.setBlockedBtoA(0);
			c.setAToB(false);
			c.setBToA(false);
			c.persist();
			
			
			Peticiones pet = new Peticiones();
	
				pet.setHora(new Date());
				pet.setTexto("__30");
				pet.setRemite(remite);
				pet.setDestinatario(destino);
				pet.setConfirmar(false);
				
				pet.persist();

				c.setAToB(false);
				c.setBToA(true);

								 
				c.setHora(new Date());
				c.setLastMsgId(pet.getId());
	
				c.merge();
				
				for(int i=0; i<members.length; i++) {
					People member=People.findPeoplesByDeviceIdEquals(members[i]).getSingleResult();
					c= new Contactos();
					c.setContactoA(destino);
					c.setContactoB(member);	
					c.setBlockedAtoB(0);
					c.setBlockedBtoA(0);
					c.setBToA(false);

					Peticiones pet2 = new Peticiones();
					
					pet2.setHora(new Date());
					pet2.setTexto("__31");
					pet2.setRemite(member);
					pet2.setDestinatario(destino);
					pet2.setConfirmar(false);					
					pet2.persist();
					
					c.setAToB(true);
					c.setLastMsgId(pet.getId());
					c.setHora(new Date());						
					c.persist();

				}

		result="{\"result\": \"OK\"}";

		} catch(Throwable e)  {
			logger.error(e.getMessage(),e);

		}

		return new ResponseEntity<String>(result, getResponseHeaders(), HttpStatus.OK);
		 
	}
	
	

	@RequestMapping(value="init", method=RequestMethod.POST, produces = "application/json")
	public @ResponseBody ResponseEntity<People> init(	HttpServletRequest request,
															@RequestParam String deviceId,
															@RequestParam String lat, 
															@RequestParam String lon,
															@RequestParam String precision,
															@RequestParam String codigoPostal,
															@RequestParam String poblacion,
															@RequestParam String provincia,
															@RequestParam String calle,										
															@RequestParam String barrio,
															@RequestParam String distrito,
															@RequestParam String region,
															@RequestParam String pais,
															@RequestParam String nombre,
															@RequestParam String desc,
															@RequestParam String ini,
															@RequestParam String end
															) {		
		
		if(deviceId.equalsIgnoreCase("-1")) deviceId=request.getHeader("X-Cluster-Client-IP");
		else if(deviceId.equalsIgnoreCase("-2")) deviceId=request.getRemoteUser();
		if(deviceId==null || deviceId.equalsIgnoreCase("")) deviceId= request.getRemoteAddr();
		
		logger.info("init peopleId for device: " + deviceId);

		
		Date iniDate = new Date(Long.parseLong(ini));
		Date endDate = new Date(Long.parseLong(end));
		
		
		Long result=-1L;
		People people =  null;	
		
		if(request.getRemoteUser()!=null && !request.getRemoteUser().equalsIgnoreCase(deviceId) && 
			!deviceId.startsWith("__") || request.getRemoteUser()!=null && deviceId.indexOf(request.getRemoteUser())<0	) {
			logger.info("Acceso incorrecto");
			return new ResponseEntity<People>(people, getResponseHeaders(), HttpStatus.OK);
		}
		
		try {		
			people=People.findPeoplesByDeviceIdEquals(deviceId).getSingleResult();

			
		} catch(Throwable e)  {
			logger.info(e.getMessage());
		}

		String photo="images/group.png";
		if(people==null) {
			if(deviceId.startsWith("__event")) {
				try {
					String auxId=deviceId.substring(deviceId.indexOf("__", 3) + 2, deviceId.indexOf("__", 10));
					photo="http://icdn.pro/images/es/k/o/kontact-fecha-icono-9647-128.png";
					people=People.findPeoplesByDeviceIdEquals(auxId).getSingleResult();					
					getConfig(request, deviceId, nombre, desc, "*", "0", people.getActivity(), "0000FF", "0.1.11", "0", "20","");					
					
				} catch(Throwable e)  {
					logger.error(e.getMessage(),e);
				}

			} else {
				getConfig(request, deviceId, nombre, desc, "N", "0", "newbieActivity", "FFFFFF", "0.1.11", "60000","20","");
			}
			people=People.findPeoplesByDeviceIdEquals(deviceId).getSingleResult();
		}

		people.setPhotoUrl(photo);

		//if(people.getGpsPrecision()==null || people.getGpsPrecision().equalsIgnoreCase("") || people.getGpsPrecision().equalsIgnoreCase("-1")) {
			
		if(!precision.equalsIgnoreCase("-1")) {
			
			if(people.getLon()==null || Double.parseDouble(precision)<100 || people.getHora()==null || (new Date()).getTime() - people.getHora().getTime() > 900000) {
				people.setLat(Double.parseDouble(lat));
				people.setLon(Double.parseDouble(lon));
				people.setGpsPrecision(precision);
				people.setHora(endDate);
			
				
			}
			
			
			people.setCodigoPostal(codigoPostal);
			people.setPoblacion(poblacion);
			people.setBarrio(barrio);
			people.setDistrito(distrito);
			people.setCalle(calle);
			people.setRegion(region);
			people.setPais(pais);
			people.setProvincia(provincia);	

		} else if(people.getLon()==null) {
			people.setLat(Double.parseDouble(lat));
			people.setLon(Double.parseDouble(lon));
			people.setGpsPrecision(precision);
		}
		
		
		people.setOnline(iniDate);

		people.merge();
		
		result=people.getId();
		

	
		logger.info("got init " + result);

		
		return new ResponseEntity<People>(people, getResponseHeaders(), HttpStatus.OK);
		 
	}
	
	@RequestMapping(value="position", method=RequestMethod.GET, produces = "application/json")
	public @ResponseBody ResponseEntity<String> setPosition(HttpServletRequest request,
															@RequestParam String id, 
															@RequestParam String lat, 
															@RequestParam String lon,
															@RequestParam String precision
															) {		
		logger.info("setting position id " + id + " with precision " + precision);

		String result="{\"result\": \"KO\"}";
		People people =  null;	
		try {
		
			people=People.findPeoplesByDeviceIdEquals(id).getSingleResult();

		
		} catch(Throwable e)  {
			logger.error(e.getMessage(),e);

		}

		
		if(people==null) {
			getConfig(request, id, "Newbie!!!", "Newbie???", "!", "60000", "newbieActivity", "FFFFFF", "test", "10000","20","");
		}

		
		String hora = (new Date()).toString();
		
		Positions pos = new Positions();
		pos.setLat(lat);
		pos.setLon(lon);
		pos.setGpsPrecision(precision);
		pos.setHora(hora);
		pos.persist();
		
		people.setLat(Double.parseDouble(lat));
		people.setLon(Double.parseDouble(lon));
		people.setGpsPrecision(precision);
		people.setOnline(new Date());
		people.setHora(new Date());
		people.getPositions().add(pos);
		
		people.merge();
		result="{\"result\": \"OK\"}";

		logger.info(" position set for id " + id );
		return new ResponseEntity<String>(result, getResponseHeaders(), HttpStatus.OK);
		 
	}
	
	
	
	@RequestMapping(value="geoLocate", method=RequestMethod.POST, produces = "application/json")
	public @ResponseBody ResponseEntity<String> geoLocate(HttpServletRequest request,
															@RequestParam String id, 
															@RequestParam String lat, 
															@RequestParam String lon,
															@RequestParam String precision,
															@RequestParam String codigoPostal,
															@RequestParam String poblacion,
															@RequestParam String provincia,
															@RequestParam String calle,										
															@RequestParam String barrio,
															@RequestParam String distrito,
															@RequestParam String region,
															@RequestParam String pais   														
															) {		
		logger.info("setting geoLocate id " + id + " with precision " + precision);

		String result="{\"result\": \"KO\"}";
		People people =  null;	
		try {
		
			people=People.findPeoplesByDeviceIdEquals(id).getSingleResult();

		
		} catch(Throwable e)  {
			logger.error(e.getMessage(),e);

		}

		
		if(people==null) {
			getConfig(request, id, "Newbie!!!", "Newbie???", "!", "60000", "newbieActivity", "FFFFFF", "test", "10000","20","");
		}

		
		Date hora = new Date();
		
		Positions pos = new Positions();
		pos.setLat(lat);
		pos.setLon(lon);
		pos.setGpsPrecision(precision);
		pos.setHora(hora.toString());
		pos.persist();
		
		people.setLat(Double.parseDouble(lat));
		people.setLon(Double.parseDouble(lon));
		people.setGpsPrecision(precision);
		people.setOnline(hora);
		people.setHora(hora);
		people.setCodigoPostal(codigoPostal);
		people.setPoblacion(poblacion);
		people.setBarrio(barrio);
		people.setDistrito(distrito);
		people.setCalle(calle);
		people.setRegion(region);
		people.setPais(pais);
		people.setProvincia(provincia);
		people.getPositions().add(pos);
		
		people.merge();
		result="{\"result\": \"OK\"}";

		logger.info(" geoLocate set for id " + id );
		return new ResponseEntity<String>(result, getResponseHeaders(), HttpStatus.OK);
		 
	}
	
	@RequestMapping(value="getPeticiones", method=RequestMethod.POST, produces = "application/json")
	public @ResponseBody ResponseEntity<List<Peticiones>> getPeticiones(HttpServletRequest request,
															@RequestParam String deviceId
															) {		
		
		List<Peticiones> pet = new ArrayList<Peticiones>();
		try {
		

			Calendar minHora = new GregorianCalendar();
			minHora.setTime(new Date());
			minHora.add(Calendar.DAY_OF_MONTH,-1);
			
			People destinatario = People.findPeoplesByDeviceIdEquals(deviceId).getSingleResult();
			pet=Peticiones.findPeticionesesByDestinatarioAndRespuestaIsNullAndConfirmar(destinatario,true).getResultList();
			//pet=Peticiones.findPeticionesesByDestinatarioAndRespuestaIsNullAndHoraGreaterThan(destinatario,minHora.getTime()).getResultList();

			//destinatario.setPeticiones(false);
			
		} catch(Throwable e)  {
			logger.error(e.getMessage(),e);
		}

		

		return new  ResponseEntity<List<Peticiones>>(pet, getResponseHeaders(), HttpStatus.OK);
		 
	}
	
	
	@RequestMapping(value="getContactos", method=RequestMethod.POST, produces = "application/json")
	public @ResponseBody ResponseEntity<List<Contactos>> getContactos(HttpServletRequest request,
															@RequestParam String deviceId
															) {		
		
		List<Contactos> contactos = new ArrayList<Contactos>();
		try {		
			
			People destinatario = People.findPeoplesByDeviceIdEquals(deviceId).getSingleResult();
			destinatario.setOnline(new Date());
			destinatario.merge();
			
			contactos=Contactos.findContactos(destinatario,2).getResultList();

			//destinatario.setPeticiones(false);
			
		} catch(Throwable e)  {
			logger.error(e.getMessage(),e);
		}

		return new  ResponseEntity<List<Contactos>>(contactos, getResponseHeaders(), HttpStatus.OK);
		 
	}
	
	@RequestMapping(value="mapContactos", method=RequestMethod.POST, produces = "application/json")
	public @ResponseBody ResponseEntity<String> mapContactos(HttpServletRequest request,
															@RequestParam String deviceId,
															@RequestParam(value="tlfns[]") String[] tlfns,
															@RequestParam(value="tlfns[]") String[] names

																) {		
		
		String result="{\"result\": \"KO\"}";

		
		try {		
			
			List<String> tels = new ArrayList<String>();
			Map<String,String> nicks = new HashMap<String,String>();

			int j=0;
			for(String tel : Arrays.asList(tlfns)) {
				char[] chars=tel.toCharArray();
				StringBuffer sb = new StringBuffer();
				for(int i=0; i<chars.length; i++) {
					if(Character.isDigit(chars[i])) {
						sb.append(chars[i]);
					}					
				}
				tels.add(sb.toString());
				nicks.put(sb.toString(), names[j++]);
			}
			
			
			
			People me =People.findPeoplesByDeviceIdEquals(deviceId).getSingleResult();

			List<People> pList= Contactos.findNewContacts(me, tels).getResultList();	
					

			for(People p : pList) {


				Contactos c=null;
				try {
					c=Contactos.findContactos(me, p,3).getSingleResult(); 
				} catch(Throwable e)  {
					logger.warn("Nuevo contacto o busqueda fallida: " + e.getMessage() );
				}

				if(c==null) {
				
					c=new Contactos();
					c.setContactoA(me);
					c.setContactoB(p);	
					c.setBlockedAtoB(0);
					c.setBlockedBtoA(0);
					c.setAToB(false);
					c.setBToA(false);
					c.setBAlias(nicks.get(p.getTelefono()));
					c.persist();

				
					Peticiones pet = new Peticiones();
		
					pet.setHora(new Date());
					pet.setTexto("__20");
					pet.setRemite(me);
					pet.setDestinatario(p);
					pet.setConfirmar(false);
					
					pet.persist();
					

					c.setAToB(true);
					c.setBToA(true);

					
					if(me.equals(p)) {
						c.setAToB(false);
						c.setBToA(false);
					}
									
					c.setHora(new Date());
					c.setLastMsgId(pet.getId());
		
					c.merge();
				}
			}

			
			result="{\"result\": \"OK\"}";
			
		} catch(Throwable e)  {
			logger.error(e.getMessage(),e);

		}

		return new  ResponseEntity<String>(result, getResponseHeaders(), HttpStatus.OK);
	}	
	
	
	@RequestMapping(value="getContactosBlocked", method=RequestMethod.POST, produces = "application/json")
	public @ResponseBody ResponseEntity<List<Contactos>> getContactosBlocked(HttpServletRequest request,
															@RequestParam String deviceId
															) {		
		
		List<Contactos> contactos = new ArrayList<Contactos>();
		try {		
			
			People destinatario = People.findPeoplesByDeviceIdEquals(deviceId).getSingleResult();
			destinatario.setOnline(new Date());
			destinatario.merge();
			contactos=Contactos.findContactos(destinatario,3).getResultList();

			//destinatario.setPeticiones(false);
			
		} catch(Throwable e)  {
			logger.error(e.getMessage(),e);
		}

		return new  ResponseEntity<List<Contactos>>(contactos, getResponseHeaders(), HttpStatus.OK);
		 
	}	
	
	@RequestMapping(value="setContactoLeido", method=RequestMethod.POST, produces = "application/json")
	public @ResponseBody ResponseEntity<String> setContactoLeido(HttpServletRequest request,
															@RequestParam String lectorId,
															@RequestParam String leidoId
															) {		
		String result="{\"result\": \"KO\"}";

		try {		
			
			People lector=People.findPeoplesByDeviceIdEquals(lectorId).getSingleResult();
			People leido=People.findPeoplesByDeviceIdEquals(leidoId).getSingleResult();	
			Contactos c=Contactos.findContactos(lector,leido,3).getSingleResult();

			if(c.getContactoA().equals(lector)) c.setBToA(false);
			else c.setAToB(false);
			
			c.merge();
			
			result="{\"result\": \"OK\"}";
			
		} catch(Throwable e)  {
			logger.error(e.getMessage(),e);

		}

		

		
		return new  ResponseEntity<String>(result, getResponseHeaders(), HttpStatus.OK);
		 
	}
	
	
	@RequestMapping(value="changeAlias", method=RequestMethod.POST, produces = "application/json")
	public @ResponseBody ResponseEntity<String> changeAlias(HttpServletRequest request,
															@RequestParam String deviceId,
															@RequestParam String aliasId,
															@RequestParam String alias															
															) {		
		String result="{\"result\": \"KO\"}";

		try {		
			
			People lector=People.findPeoplesByDeviceIdEquals(deviceId).getSingleResult();
			People leido=People.findPeoplesByDeviceIdEquals(aliasId).getSingleResult();	
			Contactos c=Contactos.findContactos(lector,leido,3).getSingleResult();

			if(c.getContactoA().equals(lector)) c.setBAlias(alias);
			else c.setAAlias(alias);
			
			c.merge();
			
			result="{\"result\": \"OK\"}";
			
		} catch(Throwable e)  {
			logger.error(e.getMessage(),e);

		}

		

		
		return new  ResponseEntity<String>(result, getResponseHeaders(), HttpStatus.OK);
		 
	}	

	@RequestMapping(value="getNewMsgs", method=RequestMethod.GET, produces = "application/json")
	public @ResponseBody ResponseEntity<List<Contactos>> getNewMsgs(HttpServletRequest request,
															@RequestParam String deviceId,
															@RequestParam(required = false) Boolean gpsStatus
															) {		
		
		List<Contactos> contactos = new ArrayList<Contactos>();
		try {		
			
			People destinatario = People.findPeoplesByDeviceIdEquals(deviceId).getSingleResult();
			if(destinatario.getGpsStatus()==null || (gpsStatus!=null && destinatario.getGpsStatus() && !gpsStatus || !destinatario.getGpsStatus() && gpsStatus)) { 
				destinatario.setGpsStatus(gpsStatus);
				destinatario.merge();
			}
			
			
			contactos=Contactos.findNewMsgs(destinatario).getResultList();

			//destinatario.setPeticiones(false);
			
		} catch(Throwable e)  {
			logger.error(e.getMessage(),e);
		}

		return new  ResponseEntity<List<Contactos>>(contactos, getResponseHeaders(), HttpStatus.OK);
		 
	}	
	
	
	@RequestMapping(value="setPeticion", method=RequestMethod.POST, produces = "application/json")
	public @ResponseBody ResponseEntity<String> setPeticion(
															@RequestParam String remiteId,
															@RequestParam String destinoId,
															@RequestParam String texto,
															@RequestParam Boolean confirmar															) {		
		String result="{\"result\": \"KO\"}";
		Peticiones pet = new Peticiones();
		try {
			
			People remite=People.findPeoplesByDeviceIdEquals(remiteId).getSingleResult();
			People destino=People.findPeoplesByDeviceIdEquals(destinoId).getSingleResult();
			
			Contactos c=null;
			try {
				c=Contactos.findContactos(remite, destino,3).getSingleResult(); //findby people ids destino en contactoA o en contactoB
			} catch(Throwable e)  {
				logger.warn("Nuevo contacto o busqueda fallida",e);
			}

			if(c==null) { 
				c=new Contactos();
				c.setContactoA(remite);
				c.setContactoB(destino);	
				c.setBlockedAtoB(0);
				c.setBlockedBtoA(0);
				c.setAToB(false);
				c.setBToA(false);
				c.persist();
			}
			
			
	
				pet.setHora(new Date());
				pet.setTexto(texto);
				pet.setRemite(remite);
				pet.setDestinatario(destino);
				pet.setConfirmar(confirmar);
				
				pet.persist();
				
				if(confirmar) {
					destino.setPeticiones(true);
					destino.merge();
				}
				//System.out.println(c.getContactoA().getId() + "," + remite.getId() + "," +  c.getContactoB().getId() + "" +destino.getId()
				//if(c.getContactoA().getId().longValue()==remite.getId().longValue() && c.getContactoB().getId().longValue()==destino.getId().longValue()) {
				if(c.getContactoA().getId().longValue()==remite.getId().longValue() && c.getContactoB().getId().longValue()==destino.getId().longValue()) {
					c.setAToB(true);
				} else if(c.getContactoB().getId().longValue()==remite.getId().longValue() && c.getContactoA().getId().longValue()==destino.getId().longValue()){
					c.setBToA(true);
				}

				if(remite.equals(destino)) {
					c.setAToB(false);
					c.setBToA(false);
				}
								
				c.setHora(new Date());
				c.setLastMsgId(pet.getId());
	
				c.merge();
				
				if(destinoId.startsWith("__activity") || destinoId.startsWith("__event") || destinoId.startsWith("__group")) {
				
					List<Contactos> lcontactos =  Contactos.findContactos(destino,2).getResultList();
					for(Contactos contacto:lcontactos) {
						if(!contacto.getContactoA().getDeviceId().equalsIgnoreCase(remiteId) && contacto.getContactoA().equals(destino)) {
							contacto.setAToB(true);
						} else if(!contacto.getContactoB().getDeviceId().equalsIgnoreCase(remiteId) && contacto.getContactoB().equals(destino)) {
							contacto.setBToA(true);
						}
						contacto.setLastMsgId(pet.getId());
						c.setHora(new Date());						
						contacto.merge();
					

					}
				}

			if(texto.equalsIgnoreCase("__12")) setAlertaAprox(remiteId,destinoId,100 ,5);

			
		} catch(Throwable e)  {
			logger.error(e.getMessage(),e);

		}

		

		
		return new  ResponseEntity<String>(result, getResponseHeaders(), HttpStatus.OK);
		 
	}
	

	@RequestMapping(value="setRecibido", method=RequestMethod.POST, produces = "application/json")
	public @ResponseBody ResponseEntity<String> setRecibido(HttpServletRequest request,
															@RequestParam String id
															) {		
		String result="{\"result\": \"KO\"}";
		
	
		Peticiones pet = null;
		try {
	
			pet=Peticiones.findPeticiones(Long.parseLong(id));
			
			if(pet.getRecibido()==null) pet.setRecibido(new Date());
			
			
			pet.merge();
			


			result="{\"result\": \"OK\"}";
			
		} catch(Throwable e)  {
			logger.error(e.getMessage(),e);

		}

		


		return new  ResponseEntity<String>(result, getResponseHeaders(), HttpStatus.OK);
		 
	}
	
	@RequestMapping(value="setRespuesta", method=RequestMethod.POST, produces = "application/json")
	public @ResponseBody ResponseEntity<String> setRespuesta(HttpServletRequest request,
															@RequestParam String id,
															@RequestParam String deviceId,
															@RequestParam String respuesta
															
															) {		
		String result="{\"result\": \"KO\"}";
		
		//List<Peticiones> pets = null;
		
		Peticiones pet = null;
		try {
	
			pet=Peticiones.findPeticiones(Long.parseLong(id));
			
			pet.setRespuesta(new Date());
			
			
			pet.merge();
			
			if(!respuesta.equalsIgnoreCase("___")) setPeticion(deviceId,pet.getRemite().getDeviceId(),respuesta,true);


//			Calendar minHora = new GregorianCalendar();
//			minHora.setTime(new Date());
//			minHora.add(Calendar.DAY_OF_MONTH,-1);
//			People p=People.findPeoplesByDeviceIdEquals(deviceId).getSingleResult();
//			pets=Peticiones.findPeticionesesByDestinatarioAndRespuestaIsNullAndHoraGreaterThan(p,minHora.getTime()).getResultList();
//
//			if(pets!=null && pets.size()>0) p.setPeticiones(true);
//			else p.setPeticiones(false);
//			
//			p.merge();
			
			result="{\"result\": \"OK\"}";
			
		} catch(Throwable e)  {
			logger.error(e.getMessage(),e);

		}

		


		return new  ResponseEntity<String>(result, getResponseHeaders(), HttpStatus.OK);
		 
	}
	
	
	@RequestMapping(value="resetBlocked", method=RequestMethod.POST, produces = "application/json")
	public @ResponseBody ResponseEntity<String> resetBlocked(HttpServletRequest request,
															@RequestParam String idA,
															@RequestParam String idB
															) {		
		return setContactRelation(idA, idB, 0);
		 
	}	
	
	@RequestMapping(value="setSilenced", method=RequestMethod.POST, produces = "application/json")
	public @ResponseBody ResponseEntity<String> setSilenced(HttpServletRequest request,
															@RequestParam String idA,
															@RequestParam String idB
															) {		
		return setContactRelation(idA, idB, 1);
		 
	}	

		
	@RequestMapping(value="setBlocked", method=RequestMethod.POST, produces = "application/json")
	public @ResponseBody ResponseEntity<String> setBlocked(HttpServletRequest request,
															@RequestParam String idA,
															@RequestParam String idB
															) {		
		return setContactRelation(idA, idB, 2);
		 
	}	

	private @ResponseBody ResponseEntity<String> setContactRelation(														
																		String idA,
																		String idB,
																		Integer rel
															) {		
		String result="{\"result\": \"KO\"}";
		
	

		try {
	
			People remite=People.findPeoplesByDeviceIdEquals(idA).getSingleResult();
			People destino=People.findPeoplesByDeviceIdEquals(idB).getSingleResult();
			
			Contactos c=Contactos.findContactos(remite, destino,3).getSingleResult(); //findby people ids destino en contactoA o en contactoB

			if(c.getContactoA().equals(remite)) { 
				c.setBlockedAtoB(rel);
			} else {
				c.setBlockedBtoA(rel);
			}
				
			c.merge();

			result="{\"result\": \"OK\"}";
			
		} catch(Throwable e)  {
			logger.error(e.getMessage(),e);

		}

		


		return new  ResponseEntity<String>(result, getResponseHeaders(), HttpStatus.OK);
		 
	}	
	
	
	@RequestMapping(value="activities", method=RequestMethod.POST)
	public @ResponseBody ResponseEntity<String>  getActvities() {
		String result="<option value='newbieActivity'>" +
		    "---" +
		    "</option>" +
		    "<option value='Walk'>" +
		    "andar" +
		    "</option>" +
		    "<option value='Tapeo'>" +
		    "tapeo" +
		    "</option>" +	
		    "<option value='Juerga'>" +
		    "juerga" +
		    "</option>" +		    
		   " <option value='Skate'>" +
		        "patines" +
		    "</option>" +
		   " <option value='Run'>" +
		        "correr" +
		   " </option>" +
		    "<option value='Bike'>" +
		        "bici" +
		    "</option>" +
		    "<option value='Moto'>" +
		        "moto" +
		   " </option>";
		

		
		
		return new  ResponseEntity<String>(result, getResponseHeaders(), HttpStatus.OK);

		 
	}
	
	
	@RequestMapping(value="setEvent", method=RequestMethod.POST, produces = "application/json")
	public @ResponseBody ResponseEntity<People> setEvent(	HttpServletRequest request,
															@RequestParam String deviceId,
															@RequestParam String lat, 
															@RequestParam String lon,
															@RequestParam String name,
															@RequestParam String comment,
															@RequestParam Date start,
															@RequestParam Date end,
															@RequestParam String activity
															) {		
		

		logger.info("setting event by  " + deviceId);

		



			getConfig(request, deviceId, "Evento", "en pruebas", "*", "60000", activity, "0000FF", "0.1.11", "10000","20","");
			People people=People.findPeoplesByDeviceIdEquals(deviceId).getSingleResult();
			

			people.setLat(Double.parseDouble(lat));
			people.setLon(Double.parseDouble(lon));
			people.setGpsPrecision("5");
			people.setHora(new Date());
			people.setOnline(new Date());
			people.merge();

		

		
		return new ResponseEntity<People>(people, getResponseHeaders(), HttpStatus.OK);
		 
	}	
	
	
	@RequestMapping(value="getChatId", method=RequestMethod.POST, produces = "application/json")
	public @ResponseBody ResponseEntity<List<Peticiones>> getChat(@RequestParam String remiteId,
														@RequestParam String destinoId,
														@RequestParam Long id
															) {		
		List<Peticiones> pets=null;
		
		People remite=People.findPeoplesByDeviceIdEquals(remiteId).getSingleResult();
		People destino=People.findPeoplesByDeviceIdEquals(destinoId).getSingleResult();
		destino.setOnline(new Date());
		destino.merge();
		
		if(remiteId.startsWith("__activity") || remiteId.startsWith("__event") || remiteId.startsWith("__group")) {
			pets = Peticiones.findChat(remite, id).getResultList();
		} else {
			pets = Peticiones.findChat(destino, remite, id).getResultList();
		}
		

		return new ResponseEntity<List<Peticiones>>(pets, getResponseHeaders(), HttpStatus.OK);
		 
	}	
	
	
	
	@RequestMapping(value="getChat", method=RequestMethod.POST, produces = "application/json")
	public @ResponseBody ResponseEntity<List<Peticiones>> getChat(@RequestParam String remiteId,
														@RequestParam String destinoId
															) {		
		List<Peticiones> pets=null;
		Calendar minHora = new GregorianCalendar();
		minHora.setTime(new Date());
		minHora.add(Calendar.DAY_OF_MONTH,-1);
		
		People remite=People.findPeoplesByDeviceIdEquals(remiteId).getSingleResult();
		People destino=People.findPeoplesByDeviceIdEquals(destinoId).getSingleResult();

		destino.setOnline(new Date());
		destino.merge();
		
		if(remiteId.startsWith("__activity") || remiteId.startsWith("__event") || remiteId.startsWith("__group")) {
			pets = Peticiones.findChat(remite, minHora.getTime());			
		} else {			
			pets = Peticiones.findChat(destino, remite, minHora.getTime());
		}
			

		return new ResponseEntity<List<Peticiones>>(pets, getResponseHeaders(), HttpStatus.OK);
		 
	}	
	
	
	@RequestMapping(value="getMsgs", method=RequestMethod.GET, produces = "application/json")
	public @ResponseBody ResponseEntity<List<Peticiones>> getMsgs(@RequestParam String destinoId
															) {		
		

		People destino=People.findPeoplesByDeviceIdEquals(destinoId).getSingleResult();
		
		Calendar minHora = new GregorianCalendar();
		minHora.setTime(new Date());
		minHora.add(Calendar.DAY_OF_MONTH,-1);
		
		List<Peticiones> pets = Peticiones.findPeticionesesByDestinatarioAndHoraGreaterThan(destino, minHora.getTime()).getResultList();

		

		return new ResponseEntity<List<Peticiones>>(pets, getResponseHeaders(), HttpStatus.OK);
		 
	}		
	
	
	@RequestMapping(value="getMsgsId", method=RequestMethod.GET, produces = "application/json")
	public @ResponseBody ResponseEntity<List<Peticiones>> getMsgsId(
														@RequestParam String destinoId,
														@RequestParam Long id
															) {		
		

		

		People destino=People.findPeoplesByDeviceIdEquals(destinoId).getSingleResult();
		
		List<Peticiones> pets = Peticiones.findPeticionesesByDestinatarioAndIdGreaterThan(destino, id).getResultList();

		

		return new ResponseEntity<List<Peticiones>>(pets, getResponseHeaders(), HttpStatus.OK);
		 
	}	
	

	@RequestMapping(value="getActivitiesCount", method=RequestMethod.POST, produces = "application/json")
	public @ResponseBody ResponseEntity<List<ActivitiesCount>> getActivitiesCount(	
																@RequestParam String deviceId,
																@RequestParam String mode) {		
		
		int OFFSET=20000;
		
		List<ActivitiesCount> acts = null;
		//List<People> people =  new ArrayList<People>();	
		try {
		
				People p = People.findPeoplesByDeviceIdEquals(deviceId).getSingleResult();
			
				if(p.getRadioKm()!=null && p.getRadioKm()>0) OFFSET=p.getRadioKm()*1000;
				
				Calendar minHora = new GregorianCalendar();
				minHora.setTime(new Date());
				minHora.add(Calendar.DAY_OF_MONTH,-1);
				
				CoordinatesConverter<LatLong, UTM> latLongToUTM = LatLong.CRS.getConverterTo(UTM.CRS);
				
				LatLong latlng = LatLong.valueOf(p.getLat(), p.getLon(), DEGREE_ANGLE);
				UTM utm = latLongToUTM.convert(latlng);
				
				UTM utmPoint = UTM.valueOf(utm.longitudeZone(), utm.latitudeZone(), 
						utm.getCoordinates()[0] - OFFSET, utm.getCoordinates()[1] + OFFSET, METER);
				
				UTM utmOffset = UTM.valueOf(utm.longitudeZone(), utm.latitudeZone(), 
						utm.getCoordinates()[0] - OFFSET + 2*OFFSET, utm.getCoordinates()[1] + OFFSET - 2*OFFSET, Length.UNIT);
				
				CoordinatesConverter<UTM,LatLong> utmToLatLong = UTM.CRS.getConverterTo(LatLong.CRS);
				LatLong llPoint = utmToLatLong.convert(utmPoint);
				LatLong llOffset = utmToLatLong.convert(utmOffset);
		
			
			
				acts=People.countActivities(mode, minHora.getTime(),p,llPoint.getCoordinates()[1],llOffset.getCoordinates()[1],llOffset.getCoordinates()[0],llPoint.getCoordinates()[0]);
				//people=People.findPeoplesByActivityEqualsAndModeEqualsAndHoraBetween(activity, mode, minHora.getTime(), maxHora.getTime()).getResultList();
				//people=People.findPeoplesByActivityEqualsAndModeEquals(activity, mode).getResultList();
				
		} catch(Throwable e)  {
			logger.error(e.getMessage(),e);
		}
		
		
		
		return new ResponseEntity<List<ActivitiesCount>>(acts, getResponseHeaders(), HttpStatus.OK);
		 
}	
	
	
	private HttpHeaders getResponseHeaders() {
		HttpHeaders responseHeaders = new HttpHeaders();
		responseHeaders.set("Access-Control-Allow-Origin", "*");
		responseHeaders.set("Access-Control-Allow-Methods", "GET, OPTIONS");
		responseHeaders.set("Access-Control-Allow-Headers", "x-requested-with");
		responseHeaders.set("Access-Control-Max-Age", "86400");
		

		return responseHeaders;
	}

	
	
	@RequestMapping(value="testSchedule", method=RequestMethod.GET)
	public @ResponseBody ResponseEntity<String> testSchedule() {
	

	String result="{\"result\": \"KO\"}";
	int ci=0;
	//doSchedule();
	

	//setPeticion("4251","4813","__40",false);
	List<AlertaAprox> aaList=AlertaAprox.findTargetWithObserver().getResultList();
	for(AlertaAprox aa:aaList) {			
		String mensaje="__42";
		if(aa.getObserver().getDeviceId().startsWith("__event")) mensaje="__43";
		setPeticion(aa.getTarget().getDeviceId(),aa.getObserver().getDeviceId(),mensaje,false);
		aa.setEstado(2);
		aa.merge();
		ci++;
		logger.info("Scheduled: " + ci);
	}
	
	result="{\"result\": \"" + ci + "\"}";
	return new  ResponseEntity<String>(result, getResponseHeaders(), HttpStatus.OK);
}
	
		@Scheduled(fixedDelay=30000)
		public void doSchedule() { 	
			
			logger.info("Scheduling: " + new Date());
		String result="{\"result\": \"KO\"}";
		int ci=0;
		//doSchedule();
		

		//setPeticion("4251","4813","__40",false);
		List<AlertaAprox> aaList=AlertaAprox.findTargetWithObserver().getResultList();
		for(AlertaAprox aa:aaList) {			
			String mensaje="__42";
			if(aa.getObserver().getDeviceId().startsWith("__event")) mensaje="__43";
			setPeticion(aa.getTarget().getDeviceId(),aa.getObserver().getDeviceId(),mensaje,false);
			aa.setEstado(2);
			aa.merge();
			ci++;
			logger.info("Scheduled: " + ci);
		}
		
		result="{\"result\": \"" + ci + "\"}";
		//return new  ResponseEntity<String>(result, getResponseHeaders(), HttpStatus.OK);
	}
	


	
	@RequestMapping(value="setAlertaAprox", method=RequestMethod.POST, produces = "application/json")
	public @ResponseBody ResponseEntity<String> setAlertaAprox(
															@RequestParam String targetId,
															@RequestParam String observerId,
															@RequestParam(required = false, defaultValue="100") Integer meters,
															@RequestParam(required = false, defaultValue="5") Integer minutes															) {		
		String result="{\"result\": \"KO\"}";

		AlertaAprox aa= new AlertaAprox();
		
		try {
			
			People target=People.findPeoplesByDeviceIdEquals(targetId).getSingleResult();
			People observer=People.findPeoplesByDeviceIdEquals(observerId).getSingleResult();
			
			aa.setTarget(target);
			aa.setObserver(observer);
			aa.setMeters(meters);
			aa.setMinutes(minutes);
			aa.setEstado(0);
			
			aa.persist();
			
			if(!aa.getObserver().getDeviceId().startsWith("__event"))
				setPeticion(aa.getObserver().getDeviceId(),aa.getTarget().getDeviceId(),"__40",false);
			
			result="{\"result\": \"OK\"}";
			
		} catch(Throwable e)  {
			logger.error(e.getMessage(),e);

		}

		return new  ResponseEntity<String>(result, getResponseHeaders(), HttpStatus.OK);
		 
	}
	
	@RequestMapping(value="unsetAlertaAprox", method=RequestMethod.POST, produces = "application/json")
	public @ResponseBody ResponseEntity<String> unsetAlertaAprox(
															@RequestParam String targetId,
															@RequestParam String observerId) {		
		String result="{\"result\": \"KO\"}";

		AlertaAprox aa=null;
		
		try {
			
			People target=People.findPeoplesByDeviceIdEquals(targetId).getSingleResult();
			People observer=People.findPeoplesByDeviceIdEquals(observerId).getSingleResult();
			
			aa=AlertaAprox.findAlertaAproxesByObserverAndTargetAndEstado(observer, target,0).getSingleResult();
			aa.setTarget(target);
			aa.setObserver(observer);
			aa.setEstado(1);
			aa.merge();
			
			setPeticion(aa.getObserver().getDeviceId(),aa.getTarget().getDeviceId(),"__41",false);
			
			result="{\"result\": \"OK\"}";
			
		} catch(Throwable e)  {
			logger.error(e.getMessage(),e);

		}

		return new  ResponseEntity<String>(result, getResponseHeaders(), HttpStatus.OK);
		 
	}
		
	
	
}
